package org.example.backend.Base.Util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.EllipticCurveJWTSigner;
import cn.hutool.jwt.signers.JWTSigner;
import org.springframework.stereotype.Component;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;
import java.util.Map;

@Component
public class JWT {

    private final static String publicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/XE5ecH6+TVIpVVt3k/lQHNITvsFsaGaRenzZm1R374hw4PAqZczGdWkHX5igY+l052lp4oGdrJw/vQ0EN1VPg==";
    private final static String privateKey = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgUB3Wiuz4uyUUTAosHET5HWSeteA1MecLvtmcZ2i5SFihRANCAAT9cTl5wfr5NUilVW3eT+VAc0hO+wWxoZpF6fNmbVHfviHDg8CplzMZ1aQdfmKBj6XTnaWnigZ2snD+9DQQ3VU+";
    private final JWTSigner signer;

    public JWT() throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory factory = KeyFactory.getInstance("EC");

        KeyPair keyPair = new KeyPair(
                factory.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKey))),
                factory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKey)))
        );
        this.signer = new EllipticCurveJWTSigner("SHA256withECDSA", keyPair);
    }

    public String create(Map<String, Object> payload) {
        return this.create(null, payload);
    }

    public String create(Map<String, Object> headers, Map<String, Object> payload) {
        Date now = DateUtil.date();

        cn.hutool.jwt.JWT jwt = cn.hutool.jwt.JWT.create();
        jwt.addHeaders(headers).addPayloads(payload).setIssuedAt(now);

        return jwt.sign(this.signer);
//        return JWTUtil.createToken(headers, payload, this.signer);
    }

    public cn.hutool.jwt.JWT parse(String token) {
        cn.hutool.jwt.JWT jwt = JWTUtil.parseToken(token);

        try {
            JWTValidator.of(jwt).validateAlgorithm(this.signer).validateDate();
        } catch (ValidateException validateException) {
            return null;
        }

        return jwt;
    }

    public boolean verify(String token) {
        cn.hutool.jwt.JWT jwt = JWTUtil.parseToken(token);

        try {
            JWTValidator.of(jwt).validateAlgorithm(this.signer).validateDate();
        } catch (ValidateException validateException) {
            return false;
        }

        return true;
    }
}
